package com.zlw.main.audioeffects;

import android.Manifest;
import android.content.Intent;
import android.media.audiofx.Visualizer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.BackgroundColorSpan;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TextView;

import com.zlw.main.audioeffects.base.MyApp;
import com.zlw.main.audioeffects.bean.LrcLine;
import com.zlw.main.audioeffects.player.AudioVisualConverter;
import com.zlw.main.audioeffects.player.MyMediaPlayer;
import com.zlw.main.audioeffects.utils.AppConfig;
import com.zlw.main.audioeffects.utils.Logger;
import com.zlw.main.audioeffects.utils.LrcUtil;
import com.zlw.main.audioeffects.utils.MusicFileHelper;
import com.zlw.main.audioeffects.utils.StrUtils;
import com.zlw.main.audioeffects.utils.UriHelper;
import com.zlw.main.audioeffects.view.AudioView;
import com.zlw.main.audioeffects.view.LineTextView;
import com.zlw.main.audioeffects.view.LrcTextView;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();
    private static final String DEFAULT_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();
    private static final String DEFAULT_LRC_PATH = DEFAULT_PATH + "/Music/暧昧-杨丞琳.lrc";

    private static final String[] PERMISSIONS = new String[]{
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.MODIFY_AUDIO_SETTINGS
    };

    private static final Map<String, Uri> MUSIC_DATA = new HashMap<>();
    private static final Map<String, Integer> MUSIC_LRC_DATA = new HashMap<>();

    {
//        MUSIC_DATA.put("grace.mp3", UriHelper.getResUri(R.raw.grace));
//        MUSIC_DATA.put("雨霖铃.mp3", UriHelper.getResUri(R.raw.yulinling));
//        MUSIC_DATA.put("China-X.mp3", UriHelper.getResUri(R.raw.china_x));
//        MUSIC_DATA.put("忆夏思乡.mp3", UriHelper.getResUri(R.raw.yixia2));
        MUSIC_DATA.put("暧昧-杨丞琳.mp3", UriHelper.getResUri(R.raw.yzlam));
        MUSIC_DATA.put("类似爱情-萧亚轩.mp3", UriHelper.getResUri(R.raw.lsaqxyx));
        MUSIC_DATA.put("是非题-范玮琪.mp3", UriHelper.getResUri(R.raw.sftfwq));
        MUSIC_LRC_DATA.put("暧昧-杨丞琳.mp3", R.raw.yzlamlrc);
        MUSIC_LRC_DATA.put("类似爱情-萧亚轩.mp3", R.raw.lsaqxyxlrc);
        MUSIC_LRC_DATA.put("是非题-范玮琪.mp3", R.raw.sftfwqlrc);
//        List<MusicFileHelper.Song> musicList = MusicFileHelper.getMusicList(MyApp.getInstance());
//        for (MusicFileHelper.Song song : musicList) {
//            MUSIC_DATA.put(song.song, UriHelper.getFileUri(song.path));
//        }
    }

    private Visualizer visualizer;
    private AudioVisualConverter audioVisualConverter;
    private boolean isInit = false;
    private AudioView audioView;
    private AudioView audioView2;
    private Spinner spinner;
    private TextView tvVoiceSize;
    private ImageView ivSwitch;
    private LrcTextView mLrcTextView;
    private LineTextView mSingleLineLrc;
    private SongLrc mCurLrc;
    private int mCurLrcPath = 0;
    private int mDefaultSongListHeight;
    private int mDefaultLrcHeight;
    private RelativeLayout mLrcIdentification;
    private MyMediaPlayer mediaPlayer;

    private Visualizer.OnDataCaptureListener dataCaptureListener = new Visualizer.OnDataCaptureListener() {
        @Override
        public void onWaveFormDataCapture(Visualizer visualizer, final byte[] waveform, int samplingRate) {
            audioView.post(new Runnable() {
                @Override
                public void run() {
                    audioView.setWaveData(waveform);
                }
            });
        }

        @Override
        public void onFftDataCapture(Visualizer visualizer, final byte[] fft, int samplingRate) {
            audioView2.post(new Runnable() {
                @Override
                public void run() {
                    audioView2.setWaveData(fft);
                    int decibel = audioVisualConverter.getVoiceSize(fft);
                    tvVoiceSize.setText(String.format(Locale.getDefault(), "当前分贝: %s db", decibel));
                    decibel = decibel / 2;
                    if (decibel > 70) {
                        decibel = 70;
                    } else if (decibel < 20) {
                        decibel = 20;
                    }
                    updateLrcTxts(decibel);
                }
            });
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS, 1);
        initView();
        initEvent();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (visualizer != null) {
            visualizer.release();
        }
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        Logger.d(TAG, "requestCode:%s", requestCode);
        initVisualizer();
    }

    private void initEvent() {
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,
                MUSIC_DATA.keySet().toArray(new String[MUSIC_DATA.size()]));
        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                if (mSingleLineLrc != null) {
                    mSingleLineLrc.setText(null);
                }
                Object item = parent.getItemAtPosition(position);
                Logger.i(TAG, "选择： %s", item.toString());
                play(MUSIC_DATA.get(item.toString()));
                loadLrcFromFile(item.toString(), item.toString(), MUSIC_LRC_DATA.get(item.toString()));
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
    }
    private void initLrcIdentification(View mLrcView) {
//        mLrcIdentification=(RelativeLayout) mLrcView.findViewById(R.id.lrc_identification);
    }
    private void initView() {
        setContentView(R.layout.activity_main);
        audioView = findViewById(R.id.audioView);
        audioView.setStyle(AudioView.ShowStyle.STYLE_HOLLOW_LUMP, AudioView.ShowStyle.STYLE_NOTHING);
        audioView2 = findViewById(R.id.audioView2);
        audioView2.setStyle(AudioView.ShowStyle.STYLE_HOLLOW_LUMP, AudioView.ShowStyle.STYLE_WAVE);
        spinner = findViewById(R.id.spinner);
        tvVoiceSize = findViewById(R.id.tvVoiceSize);
        ivSwitch = findViewById(R.id.ivSwitch);
        ivSwitch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this, Mp3Activity.class));
                finish();
            }
        });


        mLrcTextView = (LrcTextView) findViewById(R.id.lrcTextView);
        // use this to figure out the default height of the song lrctextview.
        mLrcTextView.getViewTreeObserver().addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        mDefaultLrcHeight = mLrcTextView.getHeight();
                        Log.i(TAG,"onGlobalLayout mDefaultLrcHeight == "
                                        + mDefaultLrcHeight);
                        mLrcTextView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    }
                });
        mLrcTextView.setLrcIdentificationEvent(mLrcIdentification);
        mLrcTextView.setTextEvent(mEvent);
        mLrcTextView.initActivity(this);

        mSingleLineLrc = (LineTextView) findViewById(R.id.single_line_lrc);
    }

    private static class SongLrc {
        String song;
        String artist;
        List<LrcLine> lrcLines;
        float increment;
        boolean hasTime;
    }

    private static class ComparatorLrcLine implements Comparator, Serializable {
        private static final long serialVersionUID = 1L;
        public int compare(Object arg0, Object arg1) {
            int res = 0;
            LrcLine l1 = (LrcLine) arg0;
            LrcLine l2 = (LrcLine) arg1;

            if (l1.getPos() < l2.getPos())
                res = -1;
            else if (l1.getPos() == l2.getPos())
                res = 0;
            else
                res = 1;
            return res;
        }
    }

    private void loadLrcFromFile(String artistName, String songName, int lrcId) {
        Log.i(TAG, "loadLrcFromFile songName== " + songName);
        if (mCurLrc == null) {
            mCurLrc = new SongLrc();
        }

        mCurLrcPath = lrcId;
        mCurLrc.lrcLines = new ArrayList<LrcLine>();
        mCurLrc.hasTime = LrcUtil.getLinesFromFile(mCurLrcPath, mCurLrc.lrcLines);
        mCurLrc.increment = LrcUtil.getIncrement(mCurLrcPath);
        ComparatorLrcLine cpt = new ComparatorLrcLine();
        Collections.sort(mCurLrc.lrcLines, cpt);
        mCurLrc.song = songName;
        mCurLrc.artist = artistName;
        Log.i(TAG, "loadLrcFromFile mCurLrc.hasTime== " + mCurLrc.hasTime);
        Log.i(TAG, "loadLrcFromFile mCurLrc.increment== " + mCurLrc.increment);
        Log.i(TAG, "loadLrcFromFile mCurLrc.lrcLines== " + mCurLrc.lrcLines);
        mLrcTextView.setLyricLines(mCurLrc.lrcLines);
        mLrcTextView.setHasTime(mCurLrc.hasTime);
        mLrcTextView.setIncrement(mCurLrc.increment);
        updateLrcTxts(0);
    }

    public void updateLrcTxts(int decibel) {
        try {
            if (mCurLrc == null || mCurLrc.lrcLines == null
                    || mCurLrc.lrcLines.size() == 0) {
                Log.i(TAG, "updateLrcTxts return0");
                return;
            }

            if (mediaPlayer != null) {
                int currentPosition = mediaPlayer.getCurrentPosition();
                int index = LrcUtil.getCurIndex((long) ((currentPosition + mCurLrc.increment * 1000)), mCurLrc.lrcLines);
                long indexOfString = -1;
                if (index < mCurLrc.lrcLines.size() - 1) {
                    LrcLine startLrcLine = mCurLrc.lrcLines.get(index);
                    long start = startLrcLine.getMillPos();
                    long end = mCurLrc.lrcLines.get(index + 1).getMillPos();
                    indexOfString = (currentPosition - start) * (startLrcLine.getLrcStr().length() + 1) / (end -start);
                }
                Log.i(TAG, "updateLrcTxts index" + index + "; indexOfString " + indexOfString);
                updateScrollLrc(index);
                updateLineLrc((int) indexOfString, decibel);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private void updateScrollLrc(int index) {
        if (mCurLrc != null && mCurLrc.hasTime) {
            mLrcTextView.setLyricIndex(index);
        }
    }

    private void updateLineLrc(int indexOfString, int decibel) {
        mSingleLineLrc.setVisibility(View.VISIBLE);
        // LogUtil.d("updatelinelrc", "mCurrentLrc=" + mLrcTextView.getCurrentLrc());
        String text = mLrcTextView.getCurrentLrc();
        //trim 不能去掉全角空格，需要将全角空格替换成半角空格
        if (text != null && text.trim().length() > 0
                && text.replaceAll("\u3000", " ").trim().length() > 0) {
            text = " " + text + " ";
        } else {
            mSingleLineLrc.setText(text);
            return;
        }
        SpannableStringBuilder style=new SpannableStringBuilder(text);
        int color = this.getResources().getColor(R.color.single_lrc_color);
        style.clearSpans();
        style.setSpan(new BackgroundColorSpan(color),0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        style.setSpan(new AbsoluteSizeSpan(decibel, true), indexOfString, ++indexOfString, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        mSingleLineLrc.setText(style);
    }

    private LrcTextView.DragTextEvent mEvent = new LrcTextView.DragTextEvent() {

        @Override
        public void changeEditMode(boolean isEdit) {
            if (mLrcIdentification!=null&&isEdit) {
                mLrcIdentification.setVisibility(View.INVISIBLE);
            }
//            doWhenEditModeChange(isEdit);
        }

        @Override
        public void searchLrc() {
//            if (mLrcSearch != null && mLrcSearch.getVisibility()== View.VISIBLE
//                    && mFunHelper != null) {
//                mFunHelper.handleSearchLrc();
//            }
        }
    };

    private void play(Uri uri) {
        isInit = false;
        mediaPlayer = MyMediaPlayer.getInstance();
        mediaPlayer.play(uri);
        mediaPlayer.setPlayStateListener(new MyMediaPlayer.PlayStateListener() {
            @Override
            public void onStateChange(MyMediaPlayer.PlayState state) {
                if (state == MyMediaPlayer.PlayState.STATE_PLAYING) {
                    initVisualizer();
                }
            }
        });
    }

    private void initVisualizer() {
        if (isInit) {
            return;
        }
        isInit = true;
        audioVisualConverter = new AudioVisualConverter();
        Logger.d(TAG, "initVisualizer()");
        try {
            int mediaPlayerId = MyMediaPlayer.getInstance().getMediaPlayerId();
            Logger.i(TAG, "mediaPlayerId: %s", mediaPlayerId);
            if (visualizer != null) {
                visualizer.release();
            }
            visualizer = new Visualizer(mediaPlayerId);

            int captureSize = Visualizer.getCaptureSizeRange()[1];
            int captureRate = Visualizer.getMaxCaptureRate() * 3 / 4;
            Logger.d(TAG, "精度: %s", captureSize);
            Logger.d(TAG, "刷新频率: %s", captureRate);

            visualizer.setCaptureSize(captureSize);
            visualizer.setDataCaptureListener(dataCaptureListener, captureRate, true, true);
            visualizer.setScalingMode(Visualizer.SCALING_MODE_NORMALIZED);
            visualizer.setEnabled(true);
        } catch (Exception e) {
            Logger.e(TAG, "请检查录音权限");
            isInit = false;
        }
    }

}
